/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.iwords.android;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.http.client.methods.HttpPost;
import org.json.JSONArray;
import org.json.JSONObject;

import com.iwords.android.WordLibsManager.WordLib;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.Handler.Callback;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

/**
 * Using a LogTextBox to display a scrollable text area
 * to which text is appended.
 *
 */
public class DataMigration extends Activity implements Callback{
    private Button goShowWord;
    private LogTextBox mText;
    private Handler appHandler = new Handler();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        setContentView(R.layout.data_migration);
        goShowWord = (Button) findViewById(R.id.go_show_word);
        mText = (LogTextBox) findViewById(R.id.text);
        appHandler = new Handler(this);
        mText.append("开始迁移...\n");
        final long userid = this.getIntent().getLongExtra("userid", -1);
        final long currentlib = this.getIntent().getLongExtra("currentlib", -1);
		new Thread(new Runnable() {  
	        public void run() { 
	        	migrate(userid, currentlib);
	        }
		}).start();

    }
    
    private static final int LOG_MESSAGE = 1000;
    private static final int ENABLE_BUTTON = 1001;
	@Override
	public boolean handleMessage(Message msg) {
		switch(msg.what){
			case LOG_MESSAGE : {
				mText.append(msg.obj.toString());
				return true;
			}
			case ENABLE_BUTTON :{
				this.goShowWord.setText("现在开始背单词");
				this.goShowWord.setEnabled(true);
				return true;
			}
		}
		return false;
    }
	
	private void log(String msg){
    	Message message = new Message();
    	message.what = LOG_MESSAGE;
    	message.obj = msg;
    	appHandler.sendMessage(message);

	}
    
    private void migrate(long userid, long currentlib){
        if(userid == -1){
        	log("参数不合法...\n");
        }
        List<WordStatus> statusList = history(userid);
        if(statusList.size()>0){
        	//log("待迁移数据有"+statusList.size()+"条...\n");
        }else{
        	log("没有待迁移数据...\n");
        	return;
        }
        Set<Long> libList = new HashSet<Long>();
        for(WordStatus status : statusList){
        	libList.add(status.getLibId());
        }
        log("需要迁移"+libList.size()+"个课本...\n");
        
		DBHelper dbHelper = new DBHelper(this);
		try{
	        for(Long libid : libList){
	        	WordLib lib = getLib(libid);
	        	if(lib==null){
	        		log("参数错误，不能获取课本【libid="+libid+"】...\n");
	        		break;
	        	}
	        	log("开始迁移"+lib.libName+"...\n");
	        	DBHelper.UserLibs userLib = new DBHelper.UserLibs();
	        	userLib.iscurrent = libid.equals(currentlib);
	        	userLib.libid = libid;
	        	userLib.userid = userid;
	        	userLib.pid = lib.pId;
	        	userLib.libname = lib.libName;
	    		//System.out.println("ChangeWordLib.userSelectedWordLib() to be inserted lib.libName="+lib.libName);
	    		dbHelper.insert(userLib);
	    		downloadWords(userid, libid, dbHelper);
	        }
	        //下载完课本后，将history，更新到本地
	        for(WordStatus status : statusList){
	        	dbHelper.updateStatus(userid, status.getLibId(), status.getWordId(), status.getFamiliarity(), status.getUpdateTime());
	        }
	        //最后，清理服务器端currentlib信息，只进行一次数据迁移到本地的过程
	        boolean success = this.clearCurrentlib(userid);
	        
	        if(success){
	        	log("数据迁移成功完成...\n");
	        	this.appHandler.sendEmptyMessage(ENABLE_BUTTON);
	        }
	        //System.out.println("DataMigration.migrate() success = "+success);
			Intent intent = new Intent(this, ProgressingActivity.class);
			DBHelper.UserLibs userLib = dbHelper.getCurrentLib(userid);
	        //System.out.println("DataMigration.migrate() userLib.libid = "+userLib.libid);
			intent.putExtra("currentLibId", userLib.libid);
			this.startActivity(intent);
		}finally{
			dbHelper.cleanup();
		}
    }
    
    public void goShowWord(View view){
		DBHelper dbHelper = new DBHelper(this);
		try{
			final long userid = this.getIntent().getLongExtra("userid", -1);
			Intent intent = new Intent(this, ProgressingActivity.class);
			DBHelper.UserLibs userLib = dbHelper.getCurrentLib(userid);
	        //System.out.println("DataMigration.migrate() userLib.libid = "+userLib.libid);
			intent.putExtra("currentLibId", userLib.libid);
			this.startActivity(intent);    	
		}finally{
			dbHelper.cleanup();
		}
    }
    
	private WordLib getLib(long libid){
		String href = this.getResources().getString(R.string.book_detail);
		href += libid;
		HttpPost request = new HttpPost(href);
		//System.out.println("DataMigration.getLib()! href=" + href);
		try {
			JSONObject jSONObject = ServerAccessor.access(this, request);
			boolean success = jSONObject.getBoolean("isSuccess");
			if (!success) {
				this.displayMessage(CodeUtils.decode(jSONObject.getString("message")));
				return null;
			}
			JSONObject libJSON = jSONObject.getJSONObject("defaultValue");
			WordLib wordLib = new WordLib(
					CodeUtils.decode(libJSON.getString("libname")),
					libJSON.getLong("libid"), 
					libJSON.getLong("pid"), 
					Boolean.FALSE, 
					libJSON.getInt("sysliblevel"), 
					(libJSON.getInt("sysliblevel")==4));
			return wordLib;
		}catch(Exception e){
			e.printStackTrace();
		}
		return null;
    }
	
	private int downloadWords(long userid, long libid, DBHelper dbHelper){
		String href = this.getResources().getString(R.string.sys_word_list);
		href = href + libid;
		HttpPost request = new HttpPost(href);
		//System.out.println("---DataMigration.downloadWords()! href = "+ href);
		int knownCount = 0;
		try {
			JSONObject jSONObject = ServerAccessor.access(this, request);
			boolean success = jSONObject.getBoolean("isSuccess");
			if (!success) {
				this.displayMessage(CodeUtils.decode(jSONObject.getString("message")));
				return knownCount;
			}
			JSONArray wordsList = JSONUtils.getArray(jSONObject.getJSONObject("defaultValue"));
			//System.out.println("---WordsQueueManager.loadCurrentQueue()! wordsList = " + wordsList.length());
			log("共有词汇"+wordsList.length()+"个...\n");
			Set<String> knowns = dbHelper.getUserKnowns(userid);
			for (int i = 0; i < wordsList.length(); i++) {//"wordid","syslibid","meaning","phonetics","spelling","createtime","updatetime"
				JSONObject jsonObject = wordsList.getJSONObject(i);
				DBHelper.LearningStatus status = new DBHelper.LearningStatus();
				status.userid = userid;
				status.wordid = jsonObject.optLong("wordid");
				status.libid = jsonObject.optLong("syslibid");
				status.spelling = CodeUtils.decode(jsonObject.optString("spelling"));
				status.phonetics = CodeUtils.decode(jsonObject.optString("phonetics"));
				status.meaning = CodeUtils.decode(jsonObject.optString("meaning"));
				status.createTime = new Date(System.currentTimeMillis());
				status.updateTime = new Date(System.currentTimeMillis());
				//根据用户的掌握情况，过滤掉已经记住的单词
				status.familiarity = 0;//初始化的时候是0
				if(knowns.contains(status.spelling.trim())){
					status.familiarity = 7;
					knownCount++;
				}
				dbHelper.insert(status);
				if(i>0 && i%100==0){
					log("已迁移"+i+"个...\n");
				}
			}
			log("迁移词汇"+wordsList.length()+"个...\n");
		} catch (Exception e) {
			this.displayMessage(e.getMessage());
		}
		return knownCount;
	}
    
	private boolean clearCurrentlib(long userid){
		String href = this.getResources().getString(R.string.user_clear_currentlib);
		href += userid;
		HttpPost request = new HttpPost(href);
		//System.out.println("DataMigration.clearCurrentlib()! href=" + href);
		try {
			JSONObject jSONObject = ServerAccessor.access(this, request);
			boolean success = jSONObject.getBoolean("isSuccess");
			return success;
		}catch(Exception e){
			e.printStackTrace();
		}
		return false;
	}
	
	private List<WordStatus> history(long userid){
		List<WordStatus> statusList = new ArrayList<WordStatus>();
		String href = this.getResources().getString(R.string.user_history);
		href += userid;
		HttpPost request = new HttpPost(href);
		//System.out.println("DataMigration.hasHistory()! href=" + href);
		try {
			JSONObject jSONObject = ServerAccessor.access(this, request);
			boolean success = jSONObject.getBoolean("isSuccess");
			if (!success) {
				this.displayMessage(CodeUtils.decode(jSONObject.getString("message")));
				return statusList;
			}
			JSONArray wordStatusList = JSONUtils.getArray(jSONObject.getJSONObject("defaultValue"));
			//System.out.println("---WordsQueueManager.loadCurrentQueue()! wordStatusList = " + wordStatusList.length());
			for (int i = 0; i < wordStatusList.length(); i++) {
				JSONObject jsonObject = wordStatusList.getJSONObject(i);
				WordStatus wordStatus = new WordStatus();
				Integer familiarity = jsonObject.getInt("familiarity");
				wordStatus.setFamiliarity(familiarity);
				wordStatus.setId(jsonObject.getLong("id"));
				wordStatus.setLibId(jsonObject.getLong("libid"));
				wordStatus.setUserid(jsonObject.getLong("userid"));
				wordStatus.setWordId(jsonObject.getLong("wordid"));
				wordStatus.setSpelling(CodeUtils.decode(jsonObject.getString("spelling")));
				wordStatus.setMeaning(CodeUtils.decode(jsonObject.getString("meaning")));
				wordStatus.setUpdateTime(jsonObject.getLong("updatetime"));

				if (jsonObject.has("phonetics")) {
					wordStatus.setPhonetics(CodeUtils.decode(jsonObject.getString("phonetics")));
				}
				statusList.add(wordStatus);
			}
		}catch(Exception e){
			e.printStackTrace();
		}
		return statusList;
	}
	
	private void displayMessage(String message) {
		//Looper.prepare();
		Toast t1 = Toast.makeText(this, message, Toast.LENGTH_LONG);
		t1.show();
	}

}
